package com.datahole.suffixarray.model;

import java.util.Arrays;

/**
 * 后缀数据三元组
 * @author hlyue
 * 
 */
public class Suffix {
	private int[] sa;
	// Note: the p-th suffix in sa: SA[rank[p]-1]];
	// p is the index of the array "rank", start with 0;
	// a text S's p-th suffix is S[p..n], n=S.length-1.
	private int[] rank;

	public int[] getRank() {
		return rank;
	}

	public void setRank(int[] rank) {
		this.rank = rank;
	}

	public int[] getSa() {
		return sa;
	}

	public void setSa(int[] sa) {
		this.sa = sa;
	}

	private boolean done;
	public int[] heightArray;

	public boolean isDone() {
		return done;
	}

	public void setDone(boolean done) {
		this.done = done;
	}

	public Suffix(int[] sa, int[] rank) {
		this.sa = sa;
		this.rank = rank;
	}

	public Suffix() {
	}

	public void calcHeightArray(StringBuffer sb, Suffix suffix) {
		int lengthOfSuffixArray = suffix.sa.length;// 获得后缀数组的长度
		heightArray = new int[sb.length()+1];// 定义最长公共前缀数组
		char[] characterArray = sb.toString().toCharArray();// 定义字符数组
		int[] rankArray = new int[suffix.rank.length];// 定义名次数组

		for (int i = 0; i < suffix.rank.length; i++) {
			rankArray[i] = suffix.rank[i] - 1;
		}

		Arrays.fill(heightArray, 0);
		for (int i = 0, compareIndexForHArray = 0; i < lengthOfSuffixArray; i++) {
			if (rankArray[i] == 0)
				continue;
			for (int j = suffix.sa[rankArray[i] - 1]; isNotOutOfBoundary(i
					+ compareIndexForHArray, j + compareIndexForHArray,
					characterArray.length)
					&& characterArray[i + compareIndexForHArray] == characterArray[j
							+ compareIndexForHArray];)
				compareIndexForHArray++;
			heightArray[rankArray[i]] = compareIndexForHArray;
			if (compareIndexForHArray > 0)
				compareIndexForHArray = compareIndexForHArray - 1;
		}
		heightArray[sb.length()]=0;
	}

	/**
	 * 
	 * @param length1
	 * @param length2
	 * @param lengthOfCharacterArray
	 *            是否到达输入字符串inputString的末尾了
	 * @return
	 */
	public boolean isNotOutOfBoundary(int length1, int length2,
			int lengthOfCharacterArray) {
		return length1 < lengthOfCharacterArray
				&& length2 < lengthOfCharacterArray;
	}

	public void display() {
		int[] sa = this.sa;
		int[] rank = this.rank;

		for (int i = 0; i < sa.length; i++) {
			System.out.format("%s:%s ", i,sa[i]);
		}
		System.out.println();
		System.out.println("rank array:");
		for (int i = 0; i < rank.length; i++) {
			System.out.format("%s:%s ",i, rank[i]);
		}
		System.out.println();
		System.out.println("height array:");
		for (int i = 0; i < heightArray.length; i++) {
			System.out.format("%s:%s ", i,heightArray[i]);
		}
		System.out.println();
	}
}